using System;
using System.Collections;
using System.Collections.Generic;


namespace Framework.Event
{
    public partial class EventDispatcher
    {
        private Dictionary<string, IDispatcherEvent> m_Events = new Dictionary<string, IDispatcherEvent>();

        public void AddListener(string type, FrameworkAction func)
        {
            IDispatcherEvent iEvent;
            if (!this.m_Events.TryGetValue(type, out iEvent))
            {
                iEvent = ReferencePool.Fetch<DispatcherEvent>();
                this.m_Events[type] = iEvent;
            }
            iEvent.AddAction(func);
        }

        public void AddListener<A>(string type, FrameworkAction<A> func)
        {
            IDispatcherEvent iEvent;
            if (!this.m_Events.TryGetValue(type, out iEvent))
            {
                iEvent = ReferencePool.Fetch<DispatcherEvent<A>>();
                this.m_Events[type] = iEvent;
            }
            iEvent.AddAction(func);
        }

        public void AddListener<A, B>(string type, FrameworkAction<A, B> func)
        {
            IDispatcherEvent iEvent;
            if (!this.m_Events.TryGetValue(type, out iEvent))
            {
                iEvent = ReferencePool.Fetch<DispatcherEvent<A, B>>();
                this.m_Events[type] = iEvent;
            }
            iEvent.AddAction(func);
        }

        public void AddListener<A, B, C>(string type, FrameworkAction<A, B, C> func)
        {
            IDispatcherEvent iEvent;
            if (!this.m_Events.TryGetValue(type, out iEvent))
            {
                iEvent = ReferencePool.Fetch<DispatcherEvent<A, B, C>>();
                this.m_Events[type] = iEvent;
            }
            iEvent.AddAction(func);
        }

        public void DelListener(string type, FrameworkAction func)
        {
            IDispatcherEvent iEvent;
            if (!this.m_Events.TryGetValue(type, out iEvent))
            {
                return;
            }
            iEvent.DelAction(func);
            if (iEvent.IsEmpty())
            {
                this.m_Events.Remove(type);
                ReferencePool.Recycle(iEvent as DispatcherEvent);
            }
        }

        public void DelListener<A>(string type, FrameworkAction<A> func)
        {
            IDispatcherEvent iEvent;
            if (!this.m_Events.TryGetValue(type, out iEvent))
            {
                return;
            }
            iEvent.DelAction(func);
            if (iEvent.IsEmpty())
            {
                this.m_Events.Remove(type);
                ReferencePool.Recycle(iEvent as DispatcherEvent<A>);
            }
        }

        public void DelListener<A, B>(string type, FrameworkAction<A, B> func)
        {
            IDispatcherEvent iEvent;
            if (!this.m_Events.TryGetValue(type, out iEvent))
            {
                return;
            }
            iEvent.DelAction(func);
            if (iEvent.IsEmpty())
            {
                this.m_Events.Remove(type);
                ReferencePool.Recycle(iEvent as DispatcherEvent<A, B>);
            }
        }

        public void DelListener<A, B, C>(string type, FrameworkAction<A, B, C> func)
        {
            IDispatcherEvent iEvent;
            if (!this.m_Events.TryGetValue(type, out iEvent))
            {
                return;
            }
            iEvent.DelAction(func);
            if (iEvent.IsEmpty())
            {
                this.m_Events.Remove(type);
                ReferencePool.Recycle(iEvent as DispatcherEvent<A, B, C>);
            }
        }
       
        public void BroadCast(string type)
        {
            IDispatcherEvent iEvent;
            if (!this.m_Events.TryGetValue(type, out iEvent))
            {
                return;
            }
            iEvent.Handle();
        }

        public void BroadCast<A>(string type, A a)
        {
            IDispatcherEvent iEvent;
            if (!this.m_Events.TryGetValue(type, out iEvent))
            {
                return;
            }
            iEvent.Handle(a);
        }

        public void BroadCast<A, B>(string type, A a, B b)
        {
            IDispatcherEvent iEvent;
            if (!this.m_Events.TryGetValue(type, out iEvent))
            {
                return;
            }
            iEvent.Handle(a, b);
        }

        public void BroadCast<A, B, C>(string type, A a, B b, C c)
        {
            IDispatcherEvent iEvent;
            if (!this.m_Events.TryGetValue(type, out iEvent))
            {
                return;
            }
            iEvent.Handle(a, b, c);
        }
    }
}